PROJECT = "ESP32_smart-card"
VERSION = "1.6.1"
--[[
        V1.6.1版本固件适用于
        ESP32物联网智能卡硬件版本Ver5.0
        VERSION log:
        在此版本中增加了WIFI功能，蓝牙BLE由于库文件并不完善所以没有添加
]]


local uw_name1="SuperWIFI-k"--智能卡优先连接Wifi的名称
local uw_password1="IEEE802.11ax"--智能卡优先连接Wifi的密码
local uw_name2="ConfigWIFI"--智能卡备选连接Wifi的名称（可脱离电脑切换）
local uw_password2="smartconfig"--智能卡备选连接Wifi的密码（可脱离电脑切换）


local sys = require "sys"--不管干啥，先写上这个
poweron=0--初始化变量0：已开机，但未完成初始化进程 1：已开机，已完成初始化，可正常使用


sys.taskInit(function() --设备初始化线程,我敢保证这东西只会执行一次

        if poweron==0 then

        --u8g2_OLED驱动初始化
        u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_sw", i2c_scl=4, i2c_sda=5})    --智能卡V5.0设计缺陷，目前只能使用软件模拟I2C，后续V6.0将支持硬件I2C
        --u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_hw",i2c_id=0})--硬件I2C，适用于V6版本智能卡或V5外接oled版
        u8g2.SetFont(u8g2.font_opposansm10_chinese)                                       --配置U8G2字体（中文10号字体）
        --u8g2.SetFont(u8g2.font_opposansm12_chinese)                                       --*12号中文字体（需要固件支持）

        --按键阵列GPIO初始化
        gpio.setup(12,nil,gpio.PULLUP)--上
        gpio.setup(18,nil,gpio.PULLUP)--左
        gpio.setup(19,nil,gpio.PULLUP)--下
        gpio.setup(13,nil,gpio.PULLUP)--右

        --其他GPIO初始化
        gpio.setup(6,0)  --初始化板载LED的GPIO为低电平
        --后续支持电池，这里留一个位置用于检测是否为电池供电

        --变量定义及初始化(全局变量)
        led_mode = 0 -- 0：关闭 1：常亮  2：呼吸
        page = 0   -- 0：主  -1：板载LED配置  1：温湿度传感  11：WIFI配置 12：WIFI连接配置 -11：MCU速度配置
        pled_time = 0  --控制PWM呼吸占空比
        pled_sw = 0  --切换PWM呼吸状态（渐亮/渐暗）
        clk_sw = 160 --控制MCU主频（支持40/80/160,不推荐使用40MHz）
        wlan_mode = 0 --控制WIFI模式 0:STATION模式 1:AP模式
        wlan_connect = 0 --控制连接不同的WiFi 0：首选wifi 1：备选wifi（由文件头定义）

        --WIFI功能初始化（默认为station模式）
        wlan.init()--初始化WIFI
        wlan.setMode(wlan.STATION)--默认为station模式
        wlan.setMac(1, string.fromHex("60AAF973090E"))--配置MAC地址（AP和station模式共用一个MAC）
        wlan.setMac(0, string.fromHex("60AAF973090E"))--看官方的wiki
        wlan.setHostname("ESP32-IOT-CARD")--配置智能卡名称
        wlan.setps(wlan.PS_NONE)--不使用WIFI省电
        wlan.dhcp(1)--开启DHCP服务

        --尝试NTP对时
        rtctime_set={year=2021,mon=12,day=31,hour=16,min=0,sec=0}--先设置一个，后面NTP会校准(如果跳过NTP校准将显示系统运行时间)
        rtc.set(rtctime_set)--把上面设置的内容加载到rtc里面
        sys.publish("startNTP")--启动MTP配网线程

        poweron=1
        end
end)


sys.taskInit(function ()        --主线程
        sys.waitUntil("NTPOK")
        while true do--循环执行
                sys.wait(100)   --加0.1s的等待防止按键按下被反复检测
                --log.info("date", os.date())
                if page==0 then
                        u8g2.ClearBuffer()
                        rtctime_get = rtc.get()--获取RTC时钟的数据*（注意，这东西的返回值是table类型，需要用table的语法进行操作
                        --下面这个鬼东西用来获取一大堆的数据（虽然乱，但是至少能用）
                        g_year,g_mon,g_day,g_hour,g_min,g_sec = rtctime_get["year"],rtctime_get["mon"],rtctime_get["day"],rtctime_get["hour"],rtctime_get["min"],rtctime_get["sec"]
                        u8g2.DrawUTF8("设备运行状态",25,15)
                        u8g2.DrawUTF8("MCU速度--"..mcu.getClk().."MHz",0,30)--MCU速度会优先由是否为电池供电*自动调整，再由用户手动调整（电池功能需要V6硬件版本）
                        --由WIFI模式决定显示内容
                        if wlan.getMode()==1 then
                                u8g2.DrawUTF8("WIFI模式--".."STATION",0,45)
                        elseif wlan.getMode()==2 then
                                u8g2.DrawUTF8("WIFI模式--".."AP",0,45)
                        end
                        u8g2.DrawUTF8(g_year.."."..g_mon.."."..g_day.." "..g_hour..":"..g_min..":"..g_sec,0,60)
                        u8g2.SendBuffer()
                        if gpio.get(18)==0 then
                                page=-1
                        elseif gpio.get(13)==0 then
                                page=1
                        elseif gpio.get(19)==0 then
                                page=-11
                        elseif gpio.get(12)==0 then
                                page=11
                        end
                end

                if page==-1 and led_mode==0 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("板载LED配置",25,15)
                        u8g2.DrawUTF8("常亮",0,30)
                        u8g2.DrawUTF8("关闭".."--当前选择",0,45)
                        u8g2.DrawUTF8("呼吸",0,60)
                        u8g2.SendBuffer()
                        if gpio.get(12)==0 then
                                led_mode=1
                        elseif gpio.get(19)==0 then
                                led_mode=2
                        end
                        if gpio.get(13)==0 then
                                page=0
                        end
                end
                if page==-1 and led_mode==1 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("板载LED配置",25,15)
                        u8g2.DrawUTF8("常亮".."--当前选择",0,30)
                        u8g2.DrawUTF8("关闭",0,45)
                        u8g2.DrawUTF8("呼吸",0,60)
                        u8g2.SendBuffer()
                        if gpio.get(19)==0 then
                                led_mode=0
                        end
                        if gpio.get(13)==0 then
                                page=0
                        end
                end
                if page==-1 and led_mode==2 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("板载LED配置",25,15)
                        u8g2.DrawUTF8("常亮",0,30)
                        u8g2.DrawUTF8("关闭",0,45)
                        u8g2.DrawUTF8("呼吸".."--当前选择",0,60)
                        u8g2.SendBuffer()
                        if gpio.get(12)==0 then
                                led_mode=0
                        end
                        if gpio.get(13)==0 then
                                page=0
                        end
                end

                if page==1 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("环境数据传感",25,15)
                        local h,t,r = sensor.dht1x(8, true)--h:湿度 t:温度 r:返回值（true/false）
                        --原本是有校验的，但是并没有什么用，所以直接砍了
                                t = string.sub (tostring(t/100),1,2)
                                h = string.sub (tostring(h/100),1,2)
                                u8g2.DrawUTF8("温度--"..t.."*C",0,30)
                                u8g2.DrawUTF8("湿度--"..h.."%",0,45)
                        u8g2.DrawUTF8("*传感器数据仅供参考",0,60)
                        u8g2.SendBuffer()

                        if gpio.get(18)==0 then
                                page=0
                        end
                end

                if page==-11 and clk_sw==160 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("MCU速度调整(beta)",0,15)
                        u8g2.DrawUTF8("- 使用左右键切换 +",5,30)
                        u8g2.DrawUTF8("160MHz",35,45)
                        u8g2.DrawUTF8("高性能",40,60)
                        u8g2.SendBuffer()
                        if gpio.get(18)==0 then
                                mcu.setClk(80)
                                clk_sw=80
                        end
                        if gpio.get(12)==0 then
                                page=0
                        end
                end
                if page==-11 and clk_sw==80 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("MCU速度调整(beta)",0,15)
                        u8g2.DrawUTF8("- 使用左右键切换 +",5,30)
                        u8g2.DrawUTF8("80MHz",40,45)
                        u8g2.DrawUTF8("均衡",45,60)
                        u8g2.SendBuffer()
                        if gpio.get(13)==0 then
                                mcu.setClk(160)
                                clk_sw=160
                        end
                        if gpio.get(12)==0 then
                                page=0
                        end
                end

                if page==11 and wlan_mode==0 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("WIFI配置(beta)",15,15)
                        u8g2.DrawUTF8("S 使用左右键切换 A",5,30)
                        u8g2.DrawUTF8("STATION模式",20,45)
                        u8g2.DrawUTF8("智能卡连接WLAN",10,60)
                        u8g2.SendBuffer()
                        if gpio.get(13)==0 then
                                wlan_mode=1
                        elseif gpio.get(19)==0 then
                                page=0
                        elseif gpio.get(12)==0 then
                                page=12
                        end
                end
                if page==11 and wlan_mode==1 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("WIFI配置(beta)",15,15)
                        u8g2.DrawUTF8("S 使用左右键切换 A",5,30)
                        u8g2.DrawUTF8("暂不支持AP模式",15,45)
                        u8g2.DrawUTF8("暂不支持AP模式",15,60)
                        --wlan.createAP("ESP32-IOT-CARD","ofcourseISLY32")
                        u8g2.SendBuffer()
                        if gpio.get(18)==0 then
                                --wlan.setMode(wlan.STATION)
                                wlan_mode=0
                        elseif gpio.get(19)==0 then
                                page=0
                        elseif gpio.get(12)==0 then
                                page=12
                        end
                end

                if page==12 and wlan_connect==0 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("WIFI连接(beta)",15,15)
                        u8g2.DrawUTF8("使用左右键切换",15,30)
                        u8g2.DrawUTF8("首选WIFI",35,45)
                        u8g2.DrawUTF8("此WIFI将优先连接",10,60)
                        u8g2.SendBuffer()
                        wlan.disconnect()
                        wlan.connect(uw_name1,uw_password1,1)
                        if gpio.get(13)==0 then
                                wlan_connect=1
                        elseif gpio.get(19)==0 then
                                page=11
                        end
                end
                if page==12 and wlan_connect==1 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("WIFI连接(beta)",15,15)
                        u8g2.DrawUTF8("使用左右键切换",15,30)
                        u8g2.DrawUTF8(uw_name2,0,45)
                        u8g2.SendBuffer()
                        wlan.disconnect()
                        wlan.connect(uw_name2,uw_password2,1)
                        if gpio.get(18)==0 then
                                wlan_connect=0
                        elseif gpio.get(19)==0 then
                                page=11
                        end
                end

                if led_mode==0 then     --检测led_mode这个变量，控制板载LED
                        pwm.open(6,2400,0)
                elseif led_mode==1 then
                        pwm.open(6,2400,100)
                elseif led_mode==2 then
                        pwm.open(6,2400,pled_time)
                        if pled_time<101 and pled_sw==0 then
                        pled_time=pled_time+5
                        end
                        if pled_time==50 then
                        pled_sw=1
                        end
                        if pled_time<101 and pled_sw==1 then
                        pled_time=pled_time-5
                        end
                        if pled_time==5 then
                        pled_sw=0
                        end
                end


end--这个是while true的end
end)--这个是fuction的end

sys.taskInit(function () --NTP配网线程（只会在开机时出现）
        sys.waitUntil("startNTP")
        local ntp_page=0 --0:ConfigWIFI 1:ChangyanTCH2205
        u8g2.ClearBuffer()
        u8g2.DrawUTF8("使用NTP校准RTC",10,15)
        u8g2.DrawUTF8("选择网络或跳过校准",5,30)
        u8g2.SendBuffer()
        while true do
                sys.wait(100)
                if gpio.get(12)==0 then
                        gpio.set(6,0)
                        sys.publish("NTPOK")
                        break
                end
                if gpio.get(19)==0 then
                        if ntp_page==0 then
                                wlan.disconnect()
                                wlan.connect(uw_name1,uw_password1,1)
                                u8g2.DrawUTF8("正在联网对时",0,60)
                                u8g2.SendBuffer()
                                break
                        elseif ntp_page==1 then
                                wlan.disconnect()
                                wlan.connect(uw_name2,uw_password2,1)
                                u8g2.DrawUTF8("正在联网对时",0,60)
                                u8g2.SendBuffer()
                                break
                        end
                end
                if ntp_page==0 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("使用NTP校准RTC",10,15)
                        u8g2.DrawUTF8("选择网络或跳过校准",5,30)
                        u8g2.DrawUTF8(uw_name1,0,45)
                        u8g2.SendBuffer()
                        if gpio.get(13)==0 then
                                ntp_page=1
                        end
                elseif ntp_page==1 then
                        u8g2.ClearBuffer()
                        u8g2.DrawUTF8("使用NTP校准RTC",10,15)
                        u8g2.DrawUTF8("选择网络或跳过校准",5,30)
                        u8g2.DrawUTF8(uw_name2,0,45)
                        u8g2.SendBuffer()
                        if gpio.get(18)==0 then
                                ntp_page=0
                        end
                end
        end
        ntp.init("ntp.ntsc.ac.cn")
        ntp.settz("CST-8")
end)

sys.taskInit(function () --NTP配网_LED闪烁线程
        sys.waitUntil("startNTP")
        while true do
                gpio.set(6,1)
                sys.wait(50)
                gpio.set(6,0)
                sys.wait(50)
                gpio.set(6,1)
                sys.wait(50)
                gpio.set(6,0)
                if sys.waitUntil("NTPOK",2000)==true then
                        break
                end
        end
end)

sys.subscribe("NTP_SYNC_DONE",
                function()
                        sys.publish("NTPOK")
                end
)

sys.run()
